package cn.com.cglib.proxy;

import cn.com.cglib.point.Point;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Method;
import java.util.List;

public class ProxyMethodInterceptor implements MethodInterceptor {

    private Point point;

    private Object obj;

    private List<String> enhanceMethodList;

    private boolean isAllEnhance = true;

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        Object result = null;
        Exception exception = null;
        if (isAllEnhance || (!isAllEnhance && !CollectionUtils.isEmpty(enhanceMethodList) && enhanceMethodList.contains(method.getName()))) {
            boolean flag = point.before(objects);
            if(flag){
                try {
                    result = methodProxy.invoke(obj, objects);
                } catch (Exception e) {
                    exception = e;
                }
                point.after(result,exception, objects);
            }
        }else{
            result = methodProxy.invoke(obj, objects);
        }
        return result;
    }

    public <T> T createObj(T obj,Point point){
        this.point = point;
        this.obj = obj;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(obj.getClass());
        enhancer.setCallback(this);
        T t = (T) enhancer.create();
        return t;
    }

    public <T> T createObj(T obj,Point point,boolean isAllEnhance,List<String> enhanceMethodList){
        this.isAllEnhance = isAllEnhance;
        this.enhanceMethodList = enhanceMethodList;
        return createObj(obj,point);
    }
}
